/* ------------------------------------------
 * Copyright (c) 2017, Synopsys, Inc. All rights reserved.

 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:

 * 1) Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.

 * 2) Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.

 * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
   --------------------------------------------- */
#ifndef _DW_SDIO_HAL_H_
#define _DW_SDIO_HAL_H_

/* register offset */
#define DWSDIO_REG_CTRL                 (0x000)
#define DWSDIO_REG_PWREN                (0x004)
#define DWSDIO_REG_CLKDIV               (0x008)
#define DWSDIO_REG_CLKSRC               (0x00C)
#define DWSDIO_REG_CLKENA               (0x010)
#define DWSDIO_REG_TMOUT                (0x014)
#define DWSDIO_REG_CTYPE                (0x018)
#define DWSDIO_REG_BLKSIZ               (0x01C)
#define DWSDIO_REG_BYTCNT               (0x020)
#define DWSDIO_REG_INTMASK              (0x024)
#define DWSDIO_REG_CMDARG               (0x028)
#define DWSDIO_REG_CMD                  (0x02C)
#define DWSDIO_REG_RESP0                (0x030)
#define DWSDIO_REG_RESP1                (0x034)
#define DWSDIO_REG_RESP2                (0x038)
#define DWSDIO_REG_RESP3                (0x03C)
#define DWSDIO_REG_MINTSTS              (0x040)
#define DWSDIO_REG_RINTSTS              (0x044)
#define DWSDIO_REG_STATUS               (0x048)
#define DWSDIO_REG_FIFOTH               (0x04C)
#define DWSDIO_REG_CDETECT              (0x050)
#define DWSDIO_REG_WRTPRT               (0x054)
#define DWSDIO_REG_GPIO                 (0x058)
#define DWSDIO_REG_TCMCNT               (0x05C)
#define DWSDIO_REG_TBBCNT               (0x060)
#define DWSDIO_REG_DEBNCE               (0x064)
#define DWSDIO_REG_USRID                (0x068)
#define DWSDIO_REG_VERID                (0x06C)
#define DWSDIO_REG_HCON                 (0x070)
#define DWSDIO_REG_UHS_REG              (0x074)
#define DWSDIO_REG_RST_N                (0x078)
#define DWSDIO_REG_BMOD                 (0x080)
#define DWSDIO_REG_PLDMND               (0x084)
#define DWSDIO_REG_DBADDR               (0x088)
#define DWSDIO_REG_IDSTS                (0x08C)
#define DWSDIO_REG_IDINTEN              (0x090)
#define DWSDIO_REG_DSCADDR              (0x094)
#define DWSDIO_REG_BUFADDR              (0x098)
#define DWSDIO_REG_CARD_THR_CTRL        (0x100)
#define DWSDIO_REG_UHS_REG_EXT          (0x108)
#define DWSDIO_REG_DATA                 (0x200)

/* DW AHB SDIO bit definitions */
#define DWSDIO_CTRL_BIT_RESET_CTRL      0
#define DWSDIO_CTRL_RESET_CTRL          (1 << DWSDIO_CTRL_BIT_RESET_CTRL)
#define DWSDIO_CTRL_BIT_RESET_FIFO      1
#define DWSDIO_CTRL_RESET_FIFO          (1 << DWSDIO_CTRL_BIT_RESET_FIFO)
#define DWSDIO_CTRL_BIT_RESET_DMA       2
#define DWSDIO_CTRL_RESET_DMA           (1 << DWSDIO_CTRL_BIT_RESET_DMA)

#define DWSDIO_CTRL_RESET_ALL           (DWSDIO_CTRL_RESET_CTRL | DWSDIO_CTRL_RESET_FIFO | \
					 DWSDIO_CTRL_RESET_DMA)
#define DWSDIO_CTRL_BIT_INT_ENABLE      4
#define DWSDIO_CTRL_INT_ENABLE          (1 << DWSDIO_CTRL_BIT_INT_ENABLE)

#define DWSDIO_CTRL_BIT_DMA_ENABLE      5
#define DWSDIO_CTRL_DMA_ENABLE          (1 << DWSDIO_CTRL_BIT_DMA_ENABLE)

#define DWSDIO_CTRL_BIT_ODPULLUP        24
#define DWSDIO_CTRL_ODPULLUP            (1 << DWSDIO_CTRL_BIT_ODPULLUP)

#define DWSDIO_CTRL_BIT_INTERNAL_DMA    25
#define DWSDIO_CTRL_INTERNAL_DMA        (1 << DWSDIO_CTRL_BIT_INTERNAL_DMA)

/* Register CMD field CMD_INDEX */
#define DWSDIO_CMD_BIT_CMD_INDEX        0
#define DWSDIO_CMD_MASK_CMD_INDEX       0x0000003FU

/* Register CMD field RESPONSE_EXPECT */
#define DWSDIO_CMD_BIT_RESP_EXP         6
#define DWSDIO_CMD_RESP_EXP             (1 << DWSDIO_CMD_BIT_RESP_EXP)

/* Register CMD field RESPONSE_LENGTH */
#define DWSDIO_CMD_BIT_RESP_LENGTH      7
#define DWSDIO_CMD_RESP_LENGTH          (1 << DWSDIO_CMD_BIT_RESP_LENGTH)

/* Register CMD field CHECK_RESPONSE_CRC */
#define DWSDIO_CMD_BIT_CHECK_CRC        8
#define DWSDIO_CMD_CHECK_CRC            (1 << DWSDIO_CMD_BIT_CHECK_CRC)

/* Register CMD field DATA_EXPECTED */
#define DWSDIO_CMD_BIT_DATA_EXP         9
#define DWSDIO_CMD_DATA_EXP             (1 << DWSDIO_CMD_BIT_DATA_EXP)

/* Register CMD field READ-WRITE */
#define DWSDIO_CMD_BIT_RW               10
#define DWSDIO_CMD_RW                   (1 << DWSDIO_CMD_BIT_RW)

/* Register CMD field TRANSFER_MODE */
#define DWSDIO_CMD_BIT_XFER_MODE        11
#define DWSDIO_CMD_XFER_MODE    (1 << DWSDIO_CMD_BIT_XFER_MODE)

/* Register CMD field SEND_AUTO_STOP */
#define DWSDIO_CMD_BIT_AUTO_STOP        12
#define DWSDIO_CMD_AUTO_STOP            (1 << DWSDIO_CMD_BIT_AUTO_STOP)

/* Register CMD field WAIT_PRVDATA_COMPLETE */
#define DWSDIO_CMD_BIT_PRV_DAT_WAIT     13
#define DWSDIO_CMD_PRV_DAT_WAIT         (1 << DWSDIO_CMD_BIT_PRV_DAT_WAIT)

/* Register CMD field STOP_ABORT_CMD */
#define DWSDIO_CMD_BIT_ABORT_STOP       14
#define DWSDIO_CMD_ABORT_STOP           (1 << DWSDIO_CMD_BIT_ABORT_STOP)

/* Register CMD field SEND_INITIALIZATION */
#define DWSDIO_CMD_BIT_SEND_INIT        15
#define DWSDIO_CMD_SEND_INIT            (1 << DWSDIO_CMD_BIT_SEND_INIT)

/* Register CMD field CARD_NUMBER */
#define DWSDIO_CMD_BIT_CARD_NO          16
#define DWSDIO_CMD_MASK_CARD_NO         0x001F0000U

/* Register CMD field UPDATE_CLOCK_REGISTERS_ONLY */
#define DWSDIO_CMD_BIT_BIT_UPD_CLK      21
#define DWSDIO_CMD_UPD_CLK              (1 << DWSDIO_CMD_BIT_BIT_UPD_CLK)

/* Register CMD field READ_CEATA_DEVICE */
#define DWSDIO_CMD_BIT_READ_CEATA_DEVICE 22
#define DWSDIO_CMD_READ_CEATA_DEVICE    (1 << DWSDIO_CMD_BIT_READ_CEATA_DEVICE)

/* Register CMD field CCS_EXPECTED */
#define DWSDIO_CMD_BIT_CCS_EXP          23
#define DWSDIO_CMD_CCS_EXP              (1 << DWSDIO_CMD_BIT_CCS_EXP)

/* Register CMD field ENABLE_BOOT */
#define DWSDIO_CMD_BIT_ENABLE_BOOT      24
#define DWSDIO_CMD_ENABLE_BOOT          (1 << DWSDIO_CMD_BIT_ENABLE_BOOT)

/* Register CMD field EXPECT_BOOT_ACK */
#define DWSDIO_CMD_BIT_BOOT_ACK_EXP     25
#define DWSDIO_CMD_BOOT_ACK_EXP         (1 << DWSDIO_CMD_BIT_BOOT_ACK_EXP)

/* Register CMD field DISABLE_BOOT */
#define DWSDIO_CMD_BIT_DISABLE_BOOT     25
#define DWSDIO_CMD_DISBALE_BOOT         (1 << DWSDIO_CMD_BIT_DISABLE_BOOT)

/* Register CMD field BOOT_MODE */
#define DWSDIO_CMD_BIT_BOOT_MODE        27
#define DWSDIO_CMD_BOOT_MODE            (1 << DWSDIO_CMD_BIT_BOOT_MODE)

/* Register CMD field VOLT_SWITCH */
#define DWSDIO_CMD_BIT_VOLT_SWITCH      28
#define DWSDIO_CMD_VOLT_SWITCH          (1 << DWSDIO_CMD_BIT_VOLT_SWITCH)

/* Register CMD field USE_HOLD_REG */
#define DWSDIO_CMD_BIT_USE_HOLD_REG     29
#define DWSDIO_CMD_USE_HOLD_REG         (1 << DWSDIO_CMD_BIT_USE_HOLD_REG)

/* Register CMD field START_CMD */
#define DWSDIO_CMD_BIT_START            31
#define DWSDIO_CMD_START                (1 << DWSDIO_CMD_BIT_START)

/* Register UHS_REG_EXT */
#define DWSDIO_UHS_REG_EXT_MASK_REFCLK  (0xC0000000)
#define DWSDIO_UHS_REG_EXT_BIT_REFCLK   30

#define DWSDIO_UHS_REG_EXT_MASK_CLKDRIVE (0x01800000)
#define DWSDIO_UHS_REG_EXT_BIT_CLKDRIVE 23

#define DWSDIO_UHX_REG_EXT_MASK_CLKSAMPLE (0x007f0000)
#define DWSDIO_UHX_REG_EXT_BIT_CLKSAMPLE 16

#define DWSDIO_STATUS_BIT_FIFO  (17)
#define DWSDIO_STATUS_FIFO_FULL (0x8)
#define DWSDIO_STATUS_FIFO_EMPTY (0x4)
#define DWSDIO_STATUS_MASK_FIFO (0x3ffe0000)

/* status bit */
#define DWSDIO_STATUS_DATA_BUSY         (1 << 9)

#define DWSDIO_FIFOTH_BIT_RX_WMARK  16
#define DWSDIO_FIFOTH_MASK_RX_WMARK (0xfff << DWSDIO_FIFOTH_BIT_RX_WMARK)
#define DWSDIO_FIFOTH_BIT_TX_WMARK      0
#define DWSDIO_FIFOTH_MASK_TX_WMARK (0xfff)
#define DWSDIO_FIFOTH_BIT_DMA_M_SIZE 28
#define DWSDIO_FIFOTH_MASK_DMA_M_SIZE  (0x7 << DWSDIO_FIFOTH_BIT_DMA_M_SIZE)
#define DWSDIO_FIFOTH_M_SIZE(x)         ((x) << DWSDIO_FIFOTH_BIT_DMA_M_SIZE)
#define DWSDIO_FIFOTH_TX_WMASK(x)       ((x))
#define DWSDIO_FIFOTH_RX_WMASK(x)       ((x) << DWSDIO_FIFOTH_BIT_RX_WMARK)

/* interrupt status bit */
#define DWSDIO_INT_CAD          (0x1U)          // Card Detected
#define DWSDIO_INT_RE           (0x2U)          // Response error
#define DWSDIO_INT_CD           (0x4U)          // Command Done
#define DWSDIO_INT_DTO          (0x8U)          // Data Transfer Over
#define DWSDIO_INT_TXDR         (0x10U)         // Transmit FiFo Data Request
#define DWSDIO_INT_RXDR         (0x20U)         // Receive Fifo Data request
#define DWSDIO_INT_RCRC         (0x40U)         // Response CRC error
#define DWSDIO_INT_DCRC         (0x80U)         // Data CRC error
#define DWSDIO_INT_RTO          (0x100U)        // Response Timeout
#define DWSDIO_INT_DRTO         (0x200U)        // Data read Timeout
#define DWSDIO_INT_HTO          (0x400U)        // Data starvation by Host timeout
#define DWSDIO_INT_FRUN         (0x800U)        // Fifo underrun / overrun error
#define DWSDIO_INT_HLE          (0x1000U)       // Hardware Locked write error
#define DWSDIO_INT_SBE          (0x2000U)       // Start bit error
#define DWSDIO_INT_ACD          (0x4000U)       // Auto Command Done
#define DWSDIO_INT_EBE          (0x8000U)       // End bit error
#define DWSDIO_INT_ALL          (0xFFFF)
#define DWSDIO_INT_DATA_ERR     (DWSDIO_INT_SBE | DWSDIO_INT_EBE | DWSDIO_INT_HLE | \
				 DWSDIO_INT_FRUN | DWSDIO_INT_DCRC)
#define DWSDIO_INT_DATA_TMO     (DWSDIO_INT_DRTO | DWSDIO_INT_HTO)

#define DWSDIO_ENUMERATION_FREQ (400000) /* 400 Khz for card enumeration */

#endif /* _DW_SDIO_HAL_H_ */